﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace SharpSoft.WPF.Controls
{
    /// <summary>
    /// 多媒体浏览控件
    /// </summary> 
    [TemplatePart(Name = "media", Type = typeof(MultiMediaControl))]
    public class MultiMediaBrowser : Control
    {
        static MultiMediaBrowser()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(MultiMediaBrowser), new FrameworkPropertyMetadata(typeof(MultiMediaBrowser)));
        }
        public MultiMediaBrowser()
        {
            //this.Loaded += MultiMediaBrowser_Loaded;
        }

        //private void MultiMediaBrowser_Loaded(object sender, RoutedEventArgs e)
        //{
        //    this.applyMedia();
        //}

        private MultiMediaControl media;
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            this.media = (MultiMediaControl)this.GetTemplateChild("media");
            this.applyMedia();
        }

        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            base.OnPropertyChanged(e);
            if (e.Property == SourceProperty)
            {
                this.CurrentIndex = 0;
                applyMedia();

            }
        }

        #region 属性


        /// <summary>
        /// 媒体列表
        /// </summary> 
        public Uri[] Source
        {
            get { return (Uri[])GetValue(SourceProperty); }
            set { SetValue(SourceProperty, value); }
        }

        public static readonly DependencyProperty SourceProperty =
            DependencyProperty.Register("Source", typeof(Uri[]), typeof(MultiMediaBrowser), new PropertyMetadata(null));
        /// <summary>
        /// 媒体的拉伸方式
        /// </summary>
        public Stretch Stretch
        {
            get { return (Stretch)GetValue(StretchProperty); }
            set { SetValue(StretchProperty, value); }
        }


        public static readonly DependencyProperty StretchProperty =
            DependencyProperty.Register("Stretch", typeof(Stretch), typeof(MultiMediaBrowser), new PropertyMetadata(Stretch.Fill));


        /// <summary>
        /// 是否允许下一个
        /// </summary>
        public bool CanNext
        {
            get { return (bool)GetValue(CanNextProperty); }
            private set { SetValue(CanNextProperty, value); }
        }

        public static readonly DependencyProperty CanNextProperty =
            DependencyProperty.Register("CanNext", typeof(bool), typeof(MultiMediaBrowser), new PropertyMetadata(false));


        /// <summary>
        /// 是否允许上一个
        /// </summary>
        public bool CanPrevious
        {
            get { return (bool)GetValue(CanPreviousProperty); }
            private set { SetValue(CanPreviousProperty, value); }
        }

        public static readonly DependencyProperty CanPreviousProperty =
            DependencyProperty.Register("CanPrevious", typeof(bool), typeof(MultiMediaBrowser), new PropertyMetadata(false));


        /// <summary>
        /// 当前文件索引
        /// </summary>
        public int CurrentIndex
        {
            get { return (int)GetValue(CurrentIndexProperty); }
            private set { SetValue(CurrentIndexProperty, value); }
        }

        public static readonly DependencyProperty CurrentIndexProperty =
            DependencyProperty.Register("CurrentIndex", typeof(int), typeof(MultiMediaBrowser), new PropertyMetadata(0, new PropertyChangedCallback(OnCurrentIndexChanged)));

        private static void OnCurrentIndexChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            if (sender is MultiMediaBrowser mmb)
            {
                mmb.OnCurrentIndexChanged();
            }
        }


        /// <summary>
        /// 是否自动播放媒体（视频）
        /// </summary>
        public bool AutoPlay
        {
            get { return (bool)GetValue(AutoPlayProperty); }
            set { SetValue(AutoPlayProperty, value); }
        }

        public static readonly DependencyProperty AutoPlayProperty =
            DependencyProperty.Register("AutoPlay", typeof(bool), typeof(MultiMediaBrowser), new PropertyMetadata(false));


        /// <summary>
        /// 是否自动重放媒体（视频）
        /// </summary>
        public bool AutoReplay
        {
            get { return (bool)GetValue(AutoReplayProperty); }
            set { SetValue(AutoReplayProperty, value); }
        }

        public static readonly DependencyProperty AutoReplayProperty =
            DependencyProperty.Register("AutoReplay", typeof(bool), typeof(MultiMediaBrowser), new PropertyMetadata(false));



        /// <summary>
        /// 是否循环访问
        /// </summary>
        public bool CircleVisit { get; set; } = false;



        /// <summary>
        /// 左右声道音量平衡
        /// </summary>
        public double Balance
        {
            get { return (double)GetValue(BalanceProperty); }
            set { SetValue(BalanceProperty, value); }
        }

        public static readonly DependencyProperty BalanceProperty =
            DependencyProperty.Register("Balance", typeof(double), typeof(MultiMediaBrowser), new PropertyMetadata(0d));


        /// <summary>
        /// 视频音量
        /// </summary>
        public double Volume
        {
            get { return (double)GetValue(VolumeProperty); }
            set { SetValue(VolumeProperty, value); }
        }

        public static readonly DependencyProperty VolumeProperty =
            DependencyProperty.Register("Volume", typeof(double), typeof(MultiMediaBrowser), new PropertyMetadata(1d));



        /// <summary>
        /// 是否静音
        /// </summary>


        public bool IsMuted
        {
            get { return (bool)GetValue(IsMutedProperty); }
            set { SetValue(IsMutedProperty, value); }
        }

        public static readonly DependencyProperty IsMutedProperty =
            DependencyProperty.Register("IsMuted", typeof(bool), typeof(MultiMediaBrowser), new PropertyMetadata(false));




        /// <summary>
        /// 获取用于展示当前媒体的控件
        /// </summary>
        public FrameworkElement CurrentMediaControl
        {
            get
            {
                return media?.MediaControl;
            }
        }
        #endregion

        #region 方法

        /// <summary>
        /// 设置文件夹内的文件为数据源
        /// </summary>
        /// <param name="folder"></param>
        public void SetFolderSource(string folder)
        {
            if (System.IO.Directory.Exists(folder))
            {
                var files = System.IO.Directory.GetFiles(folder);
                List<Uri> list = new List<Uri>();
                foreach (var item in files)
                {
                    Uri uri = new Uri(item);
                    var mediaType = MultiMediaControl.GetMediaType(uri);
                    if (mediaType != MultiMediaControl.MediaType.Unknow)
                    {
                        list.Add(uri);
                    }
                }
                this.Source = list.ToArray();
            }
        }
        /// <summary>
        /// 打开源目录中指定的文件
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        public int OpenFile(string filename)
        {
            int index = -1;
            if (this.Source != null)
            {
                foreach (var item in this.Source)
                {
                    index++;
                    var file = item.ToString();
                    var name = System.IO.Path.GetFileName(file);
                    if (string.Compare(filename, name, true) == 0)
                    {
                        Goto(index);
                        return index;
                    }
                }
            }
            return -1;
        }

        /// <summary>
        /// 显示下一个
        /// </summary>
        public void Next()
        {
            this.Goto(this.CurrentIndex + 1);
        }
        /// <summary>
        /// 显示上一个
        /// </summary>
        public void Previous()
        {
            this.Goto(this.CurrentIndex - 1);
        }
        /// <summary>
        /// 转到指定的位置(如果索引超出范围，不会引发异常，将视是否允许循环访问做出默认的操作。)
        /// </summary>
        /// <param name="index"></param>
        public void Goto(int index)
        {
            var count = 0;
            if (this.Source != null)
            {
                count = this.Source.Length;
            }
            if (CircleVisit)
            {
                index = index % count;
                if (index < 0)
                {
                    index = count + index;
                }
            }
            else
            {
                if (index < 0)
                {
                    index = 0;
                }
                else if (index > count - 1)
                {
                    index = count - 1;
                }
            }
            if (CurrentIndex == index)
            {//转到相同的索引则强制应用媒体
                applyMedia();
            }
            else
            {
                CurrentIndex = index;
            }

        }
        /// <summary>
        /// 打开当前媒体，仅需要在关闭媒体后需要再次打开媒体时调用
        /// </summary>
        public void OpenMedia()
        {
            this.applyMedia();
        }

        /// <summary>
        /// 应用当前位置的媒体
        /// </summary>
        private void applyMedia()
        {
            if (this.media != null)
            {
                if (this.Source == null || this.Source.Length == 0)
                {
                    this.CanNext = this.CanPrevious = false;
                    this.media.Source = null;
                    return;
                }
                if (CurrentIndex < 0 || CurrentIndex >= this.Source.Length)
                {
                    this.media.Source = null;
                    return;
                }
                if (!CircleVisit)
                {//不能循环访问 
                    this.CanPrevious = (this.CurrentIndex > 0);
                    this.CanNext = (this.CurrentIndex < this.Source.Length - 1);
                }
                else
                {//允许循环访问
                    this.CanPrevious = this.CanNext = true;
                }
                var uri = this.Source[CurrentIndex];

                this.media.Source = uri;
            }
        }
        /// <summary>
        /// 关闭媒体
        /// </summary>
        public void CloseMedia()
        {
            if (this.media != null)
            {
                this.media.Source = null;
            }
        }
        #endregion

        #region 事件
        /// <summary>
        /// 在当前媒体索引改变后触发
        /// </summary>
        public event RoutedEventHandler CurrentIndexChanged
        {
            add { AddHandler(CurrentIndexChangedEvent, value); }
            remove { RemoveHandler(CurrentIndexChangedEvent, value); }
        }

        public static readonly RoutedEvent CurrentIndexChangedEvent = EventManager.RegisterRoutedEvent(
        "CurrentIndexChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MultiMediaBrowser));

        protected virtual void OnCurrentIndexChanged()
        {
            this.applyMedia();

            RoutedEventArgs args = new RoutedEventArgs();
            args.RoutedEvent = MultiMediaBrowser.CurrentIndexChangedEvent;
            this.RaiseEvent(args);
        }

        #endregion
    }
}
